﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Configuration;
using System.Collections.Specialized;
using EnterpriseManagement;
using System.Data.SqlClient;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using System.Transactions;

namespace EnterpriseManagement.Models
{
    public enum MembershipDeleteStatus
    {
        UserNotExist,
        DeleteError,
        Success
    }

    ///为什么model要get;set；
    #region Model
    /*  MetadataType Example
    [MetadataType(typeof(UserMetaData))]
    public partial class User_Login
    {
        [DisplayName ("RememberMe")]
        public bool RememberMe{get;set;}

        public User_Login(string userName, string password, string employeeId)
        {
            user_name = userName;
            user_password = password;
            employee_id = employeeId;
        }

        public User_Login() { }
    }

    public class UserMetaData
    {
        [DisplayName ("UserName")]
        [Required]
        public String user_name { get; set; }

        [DisplayName ("Password")]
        [Required]
        public string user_password { get; set; }
    }

    [PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "The new password and confirmation password do not match.")]
    public class ChangePasswordModel
    {
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Current password")]
        public string OldPassword { get; set; }

        [Required]
        [ValidatePasswordLength]
        [DataType(DataType.Password)]
        [Display(Name = "New password")]
        public string NewPassword { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm new password")]
        public string ConfirmPassword { get; set; }
    }
    */

    

    [PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "新密码和确认密码不匹配。")]
    public class ChangePasswordModel
    {
        [Required]
        [DataType(DataType.Password)]
        [DisplayName("当前密码")]
        public string OldPassword { get; set; }

        [Required]
        [ValidatePasswordLength]
        [DataType(DataType.Password)]
        [DisplayName("新密码")]
        public string NewPassword { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [DisplayName("确认新密码")]
        public string ConfirmPassword { get; set; }
    }

    [PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "新密码和确认密码不匹配。")]
    public class RestPasswordModel
    {
        [Required]
        [DisplayName ("员工ID")]
        [ValidateEmployeeId]
        public string EmployeeId { get; set; }

        [Required]
        [ValidatePasswordLength]
        [DataType(DataType.Password)]
        [DisplayName("新密码")]
        public string NewPassword { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [DisplayName("确认新密码")]
        public string ConfirmPassword { get; set; }
    }

    public class DeleteUserModel
    {
        [Required]
        [DisplayName ("需要删除的员工ID")]
        [ValidateEmployeeId]
        public string EmployeeId { get; set; }

        [Required]
        [DisplayName ("超级密码")]
        public string SuperPassword { get; set; }
    }

    public class LogOnModel
    {
        [Required]
        [DisplayName("用户名")]
        public string UserName { get; set; }

        //[ValidatePasswordLength] /*该属性取minPasswordLength值出现异常，会导致所有attribute验证失效*/
        //*******//
        //为什么Required属性对Password不起作用。
        [Required]
        [DisplayName("密码")]
        public string Password { get; set; }

        [DisplayName("记住我?")]
        public bool RememberMe { get; set; }
    }

    [PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "两次密码输入不一致")]
    public class RecreateUserModel
    {
        [Required]
        [ValidateEmployeeId]
        public string EmployeeId { get; set; }

        [Required]
        [DisplayName ("用户名")]
        public string UserName { get; set; }

        [ValidatePasswordLength]
        [Required]
        [DisplayName("密码")]
        public string Password { get; set; }

        [Required]
        [DisplayName("确认密码")]
        public string ConfirmPassword { get; set; }
    }

    public class BasicInformationModel
    {
        [Required]
        [DisplayName("员工ID")]
        [ValidateEmployeeId]
        public string EmployeeId { get; set; }

        [Required]
        [DisplayName("姓名")]
        public string Name { get; set; }

        [DisplayName ("生日")]
        [Required]
        [ValidateDate]
        public string Birthday { get; set; }

        [DisplayName("性别")]
        [Required]
        public string Sex { get; set; }

        [DataType(DataType.EmailAddress)]
        [DisplayName("电子邮件地址")]
        public string Email { get; set; }

        [DisplayName("毕业院校")]
        public string GraduateSchool { get; set; }

        [DisplayName("专业")]
        public string Major { get; set; }

        [DisplayName("职位")]
        public string Position { get; set; }

        [DisplayName("入职时间")]
        [Required]
        [ValidateDate]
        public string HiredDate { get; set; }

        [DisplayName("电话")]
        public string Mobile { get; set; }

        [DisplayName("雇佣状态")]
        [Required]
        public string EmployeeStatus { get; set; }

        [DisplayName("离职时间")]
        public string LeaveDate { get; set; }

         public BasicInformationModel()
        { }
         public BasicInformationModel(Employee employee)
        {
            this.EmployeeId = employee.employee_id;
            this.Birthday = employee.birthday;
            this.Sex = employee.sex;
            this.Position = employee.position;
            this.Major = employee.major;
            this.Mobile = employee.mobile;
            this.HiredDate = employee.hired_date;
            this.LeaveDate = employee.leave_date;
            this.GraduateSchool = employee.graduate_school;
            this.EmployeeStatus = employee.employee_status;
            this.Email = employee.email;
            this.Name = employee.name;
        }
    }

    [PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "密码和确认密码不匹配。")]
    public class RegisterModel
    {
        [DisplayName ("员工ID")]
        [ValidateEmployeeId]
        [Required]
        [ValidateEmployeeIdExist]
        public string EmployeeId {get;set;}

        [DisplayName("姓名")]
        [Required]
        public string Name { get; set; }

        [Required]
        [DisplayName("用户名")]
        [ValidateUser]
        public string UserName { get; set; }

        [Required]
        [ValidatePasswordLength]
        [DataType(DataType.Password)]
        [DisplayName("密码")]
        public string Password { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [DisplayName("确认密码")]
        public string ConfirmPassword { get; set; }

        [DisplayName ("生日")]
        [Required]
        [ValidateDate]
        public string Birthday {get;set;}

        [DisplayName("性别")]
        [Required]
        public string Sex{get;set;}

        
        [DataType(DataType.EmailAddress)]
        [DisplayName("电子邮件地址")]
        public string Email { get; set; }

        [DisplayName("毕业院校")]
        public string GraduateSchool{get;set;}

        [DisplayName("专业")]
        public string Major{get;set;}

        [DisplayName("入职时间")]
        [Required]
        [ValidateDate]
        public string HiredDate{get;set;}

        [DisplayName("职位")]
        public string Position{get;set;}

        [DisplayName("电话")]
        [Required]
        public string Mobile{get;set;}

        [DisplayName("在职状态")]
        [Required]
        public string EmployeeStatus{get;set;}

        [DisplayName("离职时间")]
        [ValidateDate]
        public string LeaveDate{get;set;}

        public RegisterModel()
        { }
        public RegisterModel(Employee employee)
        {
            this.EmployeeId = employee.employee_id;
            this.Birthday = employee.birthday;
            this.Sex = employee.sex;
            this.Position = employee.position;
            this.Major = employee.major;
            this.Mobile = employee.mobile;
            this.HiredDate = employee.hired_date;
            this.LeaveDate = employee.leave_date;
            this.GraduateSchool = employee.graduate_school;
            this.EmployeeStatus = employee.employee_status;
            this.Email = employee.email;
            this.Name = employee.name;
        }
    }

    #endregion 

    #region DbHelper

    //DB operation class
    public partial   class DbHelper
    {
        //******//
        //Need lock when in the circumstance of multithreading 
       // private static  ProjectEntities currentContext = new ProjectEntities();

        public static bool ValidateUser(string userName, string password, out User_Login user, ProjectEntities currentContext = null)
        {
            user = null;
            //如果有传入没有传入context则不是一串连续的事务，用完context即dispose
            if (currentContext == null)
            {
                using (currentContext = new ProjectEntities())
                {
                    var users = from p in currentContext.User_Login
                                where userName == p.user_name && password == p.user_password
                                select p;
                    if (users.Count() != 0)
                    {
                        user = users.First();
                        return true;
                    }
                    return false;
                }
            }
            else
            {
                var users = from p in currentContext.User_Login
                            where userName == p.user_name && password == p.user_password
                            select p;
                if (users.Count() != 0)
                {
                    user = users.First();
                    return true;
                }
                return false;
            }
        }

        /// <summary>
        /// 通过登录的用户名获取该用户所属组,并转化成该组组名，从而得到该组权限
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static List<string> GetUserGroup(string userName)
        {
            using ( ProjectEntities currentContext=new ProjectEntities ())
            {
                List<string> groups = new List<string>();
                var groupids=from user in currentContext .User_Login
                           where user.user_name ==userName
                           select user.group_ids;
               
                string[] ids = groupids.First ().Split (',');

                int i;
                foreach (string id in ids)
                {
                    i = int.Parse(id);
                    var groupname = from g in currentContext.User_Group
                                    where g.group_id == i
                                    select g.group_name;
                    if (groupname.Count() != 0)
                        groups.Add(groupname.First ());
                }

                return groups;
            }
        }

        public static string GetUsernameById(string employeeId)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                var userNames = from e in currentContext.User_Login
                                 where e.employee_id == employeeId
                                 select e.user_name;
                if (userNames.Count() != 0)
                {
                    return userNames.First();
                }
                return null;
            }
        }

        public static bool  ChangePassword(string userName,string oldPassword,string newPassword)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                //Move this to FormsService
                User_Login user;
                if (!ValidateUser(userName, oldPassword, out user,currentContext ))
                {
                    return false;
                }
                try
                {
                    user.user_password = newPassword;
                    currentContext.SaveChanges();
                }
                catch (Exception ex)
                {
                    return false;
                }

                return true;
            }
        }

        /// <summary>
        /// 通过employeeId得到Employee对象，未找到相应对象则返回Null
        /// </summary>
        /// <param name="employeeId">employeeId</param>
        /// <returns></returns>
        public static Employee GetEmployeeById(string employeeId,ProjectEntities currentContext=null)
        {
            if (currentContext == null)                //非事务
            {
                using (currentContext = new ProjectEntities())
                {
                    var employees = from e in currentContext.Employees
                                    where e.employee_id == employeeId
                                    select e;
                    if (employees.Count() > 0)
                    {
                        return employees.First();
                    }
                    else
                    {
                        return null;
                    }
                }
            }
            else
            {
                var employees = from e in currentContext.Employees
                                where e.employee_id == employeeId
                                select e;
                if (employees.Count() > 0)
                {
                    return employees.First();
                }
                else
                {
                    return null;
                }
            }
        }

        //Employee table contain all employees including left employee
        //User table just contain current employee
        public static MembershipCreateStatus CreateUser(string userName, string password, string employeeId,ProjectEntities currentContext=null)
        {
            ProjectEntities originalContext = currentContext;
            if (currentContext == null)                             //非事务
            {
                currentContext = new ProjectEntities();
            }
            User_Login newUser = User_Login.CreateUser_Login(employeeId, userName, password, "0");
            try
            {
                currentContext.User_Login.AddObject(newUser);
                if (originalContext == null)
                {
                    currentContext.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                currentContext.Dispose();
                return MembershipCreateStatus.UserRejected;
            }
            return MembershipCreateStatus.Success;
        }

        /*Old CreateEmployee
        //Create Employee,including account
        public static MembershipCreateStatus CreateEmployee(string employeeId, string userName, string password, string birthday, string sex, string hiredDate, string mobile,
                                                            string employStatus, string email = "", string graduateSchool = "", string major = "", string position = "",
                                                            string leaveDate = "")
        {
           
            var ids = from p in currentContext.Employees
                      select p.employee_id;
            foreach (var id in ids)
            {
                if (id == employeeId)
                {
                    return MembershipCreateStatus.DuplicateProviderUserKey;
                }
            }

            Employee employee = new Employee();
            employee.employee_id = employeeId;
            employee.birthday = birthday;
            employee.sex = sex;
            employee.hired_date = hiredDate;
            employee.mobile = mobile;
            employee.employee_status = employStatus;
            employee.email = email;
            employee.graduate_school = graduateSchool;
            employee.major = major;
            employee.position = position;
            employee.leave_date = leaveDate;

            try
            {
                currentContext.Employees.AddObject(employee);
                currentContext.SaveChanges();
            }
            catch (Exception ex)
            {
                currentContext.Employees.Detach(employee);
                //UserRejected mean something goes wrong when saving changes to database;
                return MembershipCreateStatus.UserRejected ;
            }

            MembershipCreateStatus createUserResult = CreateUser(userName, password, employeeId);

            return createUserResult;
        }
        */

        public static MembershipCreateStatus CreateEmployee(RegisterModel model)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                Employee employee = new Employee(model);
                currentContext.Employees.AddObject(employee);
                MembershipCreateStatus createUserResult = CreateUser(model.UserName, model.Password, model.EmployeeId,currentContext);
                try
                {
                    currentContext.SaveChanges();
                }
                catch (Exception ex)
                {
                    currentContext.Dispose();
                    return MembershipCreateStatus.UserRejected;
                }
                return MembershipCreateStatus.Success;
            }
        }
        /// <summary>
        /// 员工离职时调用,包含transaction
        /// </summary>
        /// <param name="employeeId"></param>
        /// <param name="superPassword"></param>
        /// <returns></returns>
        public static MembershipDeleteStatus DeleteUser(string employeeId, string superPassword)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                User_Login superUser = null;
                if (!ValidateUser(HttpContext.Current.User.Identity.Name, superPassword, out superUser, currentContext))
                {
                    //wrong superPassword 
                    return MembershipDeleteStatus.DeleteError;
                }

                Employee e = DbHelper.GetEmployeeById(employeeId,currentContext);
                User_Login userTobeDeleted = DbHelper.GetUserById(employeeId, currentContext);
                if (e == null||userTobeDeleted ==null)
                {
                    return MembershipDeleteStatus.DeleteError;
                }
                try
                {
                    //更新员工基本信息
                    e.leave_date = GetFormatNowDate();
                    e.employee_status = "Off";
                    currentContext.User_Login.DeleteObject(userTobeDeleted);
                    DbHelper.ReleaseTeamMember(userTobeDeleted.employee_id, null, currentContext);
                    currentContext.SaveChanges();
                }
                catch (Exception ex)
                {
                    return MembershipDeleteStatus.DeleteError;
                }
                return MembershipDeleteStatus.Success;
            }
        }


        public static User_Login GetUserById(string employeeId,ProjectEntities currentContext = null)
        {
            if (currentContext == null)              //非事务
            {
                using (currentContext = new ProjectEntities())
                {
                    var users = from p in currentContext.User_Login
                                where p.employee_id == employeeId
                                select p;
                    if (users.Count() == 0)
                    {
                        return null;
                    }
                    return users.First();
                }
            }
            else
            {
                var users = from p in currentContext.User_Login
                            where p.employee_id == employeeId
                            select p;
                if (users.Count() == 0)
                {
                    return null;
                }
                return users.First();
            }
        }



        public static Employee GetEmployeeByUserName(string userName)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                var employees = from e in currentContext.Employees
                                from u in currentContext.User_Login
                                where e.employee_id == u.employee_id && u.user_name == userName
                                select e;
                if (employees.Count() <= 0)
                    return null;

                return employees.First();
            }
        }

        public static bool ChangeBasicInformation(Employee employee)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                var employeeCollection = from e in currentContext.Employees
                                         where e.employee_id == employee.employee_id
                                         select e;
                Employee employeeToBeUpdated = employeeCollection.First();
                employeeToBeUpdated.Update(employee);
                try
                {
                    currentContext.SaveChanges();
                }
                catch (Exception ex)
                {
                    return false;
                }

                return true;
            }
        }

        public static bool ResetPassword(string employeeId, string newPassword)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                var user = from u in currentContext.User_Login
                           where u.employee_id == employeeId
                           select u;
                if (user.Count() <= 0)
                {
                    return false;
                }
                User_Login userToBeUpdated = user.First();
                userToBeUpdated.user_password = newPassword;
                try
                {
                    currentContext.SaveChanges();
                }
                catch (SqlException sqlex)
                {
                    return false;
                }

                return true;
            }
        }

        public static bool EmployeeExist(string employeeId)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                var employees = from e in currentContext.Employees
                                where e.employee_id == employeeId
                                select e;

                if (employees.Count() >= 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        public static bool EmployeeExistUser(string employeeId)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                var users = from e in currentContext.User_Login
                            where e.employee_id == employeeId
                            select e;

                if (users.Count() <= 0)
                {
                    return false;
                }

                return true;
            }
        }

        public static ExecuteResult UpdateEmployeeById(BasicInformationModel model)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                var e = from em in currentContext.Employees
                        where model.EmployeeId == em.employee_id
                        select em;
                if (e.Count() != 1)
                {
                    return ExecuteResult.UpdateEmployeeError;
                }
                try
                {
                    Employee newEmployee = new Employee(model);
                    e.First().Update(newEmployee);
                    currentContext.SaveChanges();
                }
                catch (Exception ex)
                {
                    return ExecuteResult.UpdateEmployeeError;
                }
                return ExecuteResult.Success;
            }
        }

    }

    #endregion

    #region FormsService

    //Account operation class
    public partial   class FormsService
    {
        public static Employee GetEmployeeById(string employeeId)
        {
            return DbHelper.GetEmployeeById(employeeId);
        }

        /// <summary>
        /// 通过BasicInformationModel更新员工基本信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static ExecuteResult UpdateEmployeeById(BasicInformationModel model)
        {
            return DbHelper.UpdateEmployeeById(model);
        }

        public static  void SignIn(string userName, bool createPersistentCookie)
        {
            if (string.IsNullOrEmpty(userName))
            {
                throw new ArgumentException("Value cannot be null or empty.", "userName");
            }
            FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
        }

        public static  void SignOut()
        {
            FormsAuthentication.SignOut();
        }

        public static Employee GetEmployeeByUserName(string userName)
        {
            return DbHelper.GetEmployeeByUserName(userName);
        }

        public static  bool ValidateUser(string userName, string password)
        {
            User_Login user;
            userName = userName.Replace("'", "''");
            password = password.Replace("'", "''");

            if (string.IsNullOrEmpty(userName)) throw new Exception("userName can not be empty");
            if (string.IsNullOrEmpty(password)) throw new Exception("password can not be empty");

            return DbHelper.ValidateUser(userName, password,out user);
        }

        public static bool ChangeBasicInformation(Employee employee)
        {
            return DbHelper.ChangeBasicInformation(employee);
        }

        //Maybe can change parameters to registermodel
         public static MembershipCreateStatus CreateEmployee(RegisterModel model)
         {
             return DbHelper.CreateEmployee(model);
        }

        public static  bool ChangePassword(string oldPassword, string newPassword)
        {
            if (string.IsNullOrEmpty(oldPassword) || string.IsNullOrEmpty(newPassword))
            { return false; }
            
            //string userName = FormsAuthentication.FormsCookieName;
            string userName = HttpContext.Current.User.Identity.Name;
            if (DbHelper.ChangePassword(userName, oldPassword, newPassword))
            { return true; }
            else
            { return false; }
        }

        public static bool ResetPassowrd(string employeeId, string newPassword)
        {
            if (DbHelper.ResetPassword(employeeId, newPassword))
            {
                return true;
            }

            return false;
        }

        public static MembershipDeleteStatus DeleteUser(string employeeId, string superPassword)
        {
            string userName = HttpContext.Current.User.Identity.Name;
            string selfEmployeeId = DbHelper.GetEmployeeByUserName(userName).employee_id;
            if (selfEmployeeId == employeeId)
            {
                return MembershipDeleteStatus.DeleteError;
            }
            return ( DbHelper.DeleteUser(employeeId, superPassword));
        }

        public static bool EmployeeExistWithoutUser(string employeeId)
        {
            if (DbHelper.EmployeeExist(employeeId) && !DbHelper.EmployeeExistUser(employeeId ))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断是否挺有超管权限
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static bool IsSuper(string userName)
        {
            if (DbHelper.GetUserGroup(userName).Contains("Super"))
                return true;
            return false;
        }

        public static MembershipCreateStatus  ReCreateUser(RecreateUserModel model)
        {
            return DbHelper.CreateUser(model.UserName,model.Password , model.EmployeeId);
        }

        /// <summary>
        /// 判断是否为超级用户,从而根据用户权限进行UI排版
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static bool SuperUser(string userName)
        {
            List<string> groups = DbHelper.GetUserGroup(userName);
            if (groups.Contains("Super"))
                return true;
            else
                return false;
        }
    }

    #endregion 

    #region Validation
    /// <summary>
    /// 日期可以为空；不为空则必须形如：20110501，现在只能验证是否为8位数字，由于不支持控件，以后可以写个日期控件
    /// </summary>
    public class ValidateDateAttribute : ValidationAttribute
    {
        private const string defaultErrorMessage = "日期格式不对";

        public ValidateDateAttribute() : base(defaultErrorMessage) { }

        public override bool IsValid(object value)
        {
            if (value ==null )
                return true ;
            string date = value as string;
            Regex r = new Regex(@"^\d{8}$");
            return r.IsMatch(date);
        }
    }

    /// <summary>
    /// 验证用户名是否已存在
    /// </summary>
    public class ValidateUserAttribute : ValidationAttribute
    {
        private const string defaultErrorMessage = "用户名已存在";

        public ValidateUserAttribute() : base(defaultErrorMessage) { }

        public override bool IsValid(object value)
        {
            string userName = value as string;
            if (string.IsNullOrEmpty (userName))
                return false;
            if (UserNameExist(userName))
                return false;
            return true;

        }

        private bool UserNameExist(string userName)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                var user = from u in currentContext.User_Login
                           where userName.Trim() == u.user_name
                           select u;
                if (user.Count() > 0)
                    return true;
                return false;
            }
        }

    }

    public class KeepParentModelErrorsAttribute : FilterAttribute, IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.ParentActionViewContext == null)
                return;

            var parentContext = filterContext.ParentActionViewContext;

            var modelState = filterContext.Controller.ViewData.ModelState;
            foreach (var modelStateItem in parentContext.ViewData.ModelState)
            {
                if (modelState.ContainsKey(modelStateItem.Key))
                {
                    foreach (var error in modelStateItem.Value.Errors)
                    {
                        if (!modelState[modelStateItem.Key].Errors.Contains(error))
                            modelState[modelStateItem.Key].Errors.Add(error);
                    }
                }
                else
                {
                    filterContext.Controller.ViewData.ModelState.Add(modelStateItem);
                }
            }
        }

        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            //Nothing to do here
        }
    }


    public class ValidateEmployeeIdAttribute : ValidationAttribute
    {
        private const string defaultErrorMessage = "员工ID必须是8位数字";

        public ValidateEmployeeIdAttribute() : base(defaultErrorMessage) { }

        public override bool IsValid(object value)
        {
            if (value == null)
                return false;
            string id = value as string;
            Regex r = new Regex(@"^\d{8}$");
            return r.IsMatch (id);
        }
    }

    public class AuthorizeGroupAttribute : AuthorizeAttribute
    {
        public string Group { get; set; }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            string user = httpContext.User.Identity.Name;
            List<string> groups = DbHelper.GetUserGroup(user);
            if (groups.Contains(Group))
                return true;
            else
                return false;

        }
    }

    public class ValidateEmployeeIdExistAttribute : ValidationAttribute
    {
        private const string defaultErrorMessage = "员工ID已存在";

        public ValidateEmployeeIdExistAttribute() : base(defaultErrorMessage) { }

        public override bool IsValid(object value)
        {
            string id = value as string;
            if (string.IsNullOrEmpty(id))
                return false;
            if (EmployeeIdExist(id))
                return false;
            return true;
        }

        private bool EmployeeIdExist(string employeeId)
        {
            using (ProjectEntities currentContext = new ProjectEntities())
            {
                var ids = from e in currentContext.Employees
                         where e.employee_id.Trim() == employeeId.Trim()
                         select e;
                if (ids.Count() > 0)
                    return true;
                return false;
            }
        }
    }

    public class ValidatePasswordLengthAttribute : ValidationAttribute
    {
        private readonly  int minLength;
        private readonly int maxLength;
        private const string defaultErrorMessage = "{0}长度必须大于{1}位小于{2}";
     
        public ValidatePasswordLengthAttribute()
            : base(defaultErrorMessage)
        {
            string[] passwordLength = GetPasswordLength();
            minLength = int.Parse(passwordLength[0]);
            maxLength = int.Parse(passwordLength[1]);
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format(CultureInfo.CurrentCulture, ErrorMessageString,
                name, minLength,maxLength);
        }

        public override bool IsValid(object value)
        {
            string valueAsString = value as string;
            return (!string.IsNullOrEmpty (valueAsString) && valueAsString.Length >= minLength&&valueAsString.Length <=maxLength);
        }

        //读XML，选择出元素就行，最后再从中取值，如果一开始就取值，select出来的集合会变成char[]
        private string[] GetPasswordLength()
        {
            string configPath = HttpContext.Current.Server.MapPath("/Config.xml");
            XElement element = XElement.Load(configPath);
            var minLength = from min in element.Element("AccountValidation").Elements("MinPasswordLength")
                            select min.Value ;
            var  maxLength = from max in element.Element("AccountValidation").Elements("MaxPasswordLength")
                            select max.Value ;

            string[] length = { minLength.First(), maxLength.First()};
            return length;
        }
    }

    public static class AccountValidation
    {
        public static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // 请参见 http://go.microsoft.com/fwlink/?LinkID=177550 以查看
            // 状态代码的完整列表。
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "用户名已存在。请另输入一个用户名。";

                case MembershipCreateStatus.InvalidPassword:
                    return "提供的密码无效。请输入有效的密码值。";

                case MembershipCreateStatus.InvalidUserName:
                    return "提供的用户名无效。请检查该值并重试。";

                case MembershipCreateStatus.DuplicateProviderUserKey:
                    return "员工ID已存在，请确认填写的员工ID是否正确";

                case MembershipCreateStatus.UserRejected:
                    return "已取消用户创建请求。请验证您的输入并重试。如果问题仍然存在，请与系统管理员联系。";

                default:
                    return "发生未知错误。请验证您的输入并重试。如果问题仍然存在，请与系统管理员联系。";
            }
        }
    }

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public sealed class PropertiesMustMatchAttribute : ValidationAttribute
    {
        private const string _defaultErrorMessage = "'{0}' 和 '{1}' 不匹配。";
        private readonly object _typeId = new object();

        public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty)
            : base(_defaultErrorMessage)
        {
            OriginalProperty = originalProperty;
            ConfirmProperty = confirmProperty;
        }

        public string ConfirmProperty { get; private set; }
        public string OriginalProperty { get; private set; }

        public override object TypeId
        {
            get
            {
                return _typeId;
            }
        }

        public override string FormatErrorMessage(string name)
        {
            return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
                OriginalProperty, ConfirmProperty);
        }

        public override bool IsValid(object value)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
            object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value);
            object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value);
            return Object.Equals(originalValue, confirmValue);
        }
    }

    #endregion 
}
